package cn.biplam.back.bean.ddl;

import java.util.ArrayList;

import cn.biplam.back.bean.ddl.sql2db.TableParser;
import cn.biplam.back.jda.Jda;
import cn.biplam.back.sql.ddl.Database;
import cn.biplam.back.sql.ddl.Table;
import cn.biplam.common.bean.sqlengine.Sql;
import cn.biplam.common.client.DbResource;
import cn.biplam.common.file.ObjectFile;
import cn.biplam.common.tools.DEBUG;
import cn.biplam.common.tools.TOOLS;
import cn.biplam.common.wrapper.ErrorMessage;
import cn.biplam.common.wrapper.KvMap;

/**
 * 源数据信息元数据化
 * @author 	WangSong	2009-3-24 下午04:49:23
 * @version 1.0
 */
public class Sql2Db {

	/**目标元数据数据库数据源*/
	private DbResource trgDb;
	/**需要操作的表*/
	private ArrayList<Table> kvmTable;

	/**
	 * 构造方法
	 * @param mdDbResource    md数据库数据源
	 * @param kvmTable        需要操作的表
	 */
	public Sql2Db(DbResource mdDbResource,ArrayList<Table> kvmTable){
		this.trgDb = mdDbResource;
		this.kvmTable = kvmTable;
	}

	/**
	 * 构造方法 
	 *   <li>从文件来初始化DataBase对象
	 * @param mdDbResource Db的数据源
	 * @param fileName 被序列化的DataBase对象文件名称
	 * @param filePath 被序列化的DataBase对象文件路径
	 * @throws ErrorMessage 
	 */
	public Sql2Db(DbResource mdDbResource,String fileName,String filePath) throws ErrorMessage{
		/**判断文件路径和文件名*/
		TOOLS.checkNull(fileName, 
		" Sql2Db(DbResource mdDbResource,String fileName,String filePath) error,fileName");
		TOOLS.checkNull(filePath, 
		" Sql2Db(DbResource mdDbResource,String fileName,String filePath) error,filePath");
		Database db = (Database)new ObjectFile(fileName+"/"+filePath).get();
		if(db!=null){
			kvmTable = db.getTableSet();
		}
	}

	/**
	 * 返回sql2db TableParser对象
	 * @return	KvMap<String,TableParser>
	 * @throws 	ErrorMessage
	 */
	public KvMap<String,TableParser> get() throws ErrorMessage{
		/**初始化Table对象*/
		Table mTable = null;
		TableParser mTableParser = null;
		KvMap<String,TableParser> tableParsers = new  KvMap<String,TableParser>();
		if(kvmTable != null) {	
			for(int i=0;i<kvmTable.size();i++){
				mTable = kvmTable.get(i);

				/**创建sql2Md解析对象*/
				mTableParser = new TableParser(this.trgDb,mTable);
				tableParsers.put(mTable.getPhysicalName(), mTableParser);
			}
		}
		return tableParsers;
	}

	/**
	 * 将DDL模型导入到数据库
	 * @throws ErrorMessage
	 */
	public void ddlExecute(boolean ignoreSqlError) throws ErrorMessage{
		boolean success=false;
		DEBUG.println("执行DDL,目标数据源:"+this.trgDb.getDsname()+" ...");
		Jda mJda = new Jda(this.trgDb,false);
		try{
			tableExecute(ignoreSqlError,mJda);
			fkExecute(ignoreSqlError,mJda);
			success=true;
		}catch(ErrorMessage e) {
			DEBUG.println("\n【Error】\t"+e.getMessage());
		}finally{
			mJda.connClose();
		}
		if(success)
			DEBUG.println("执行DDL完成!");
	}


	/**
	 * 执行DDL语句
	 * @throws ErrorMessage
	 */
	private void tableExecute(boolean ignoreSqlError,Jda mJda) throws ErrorMessage{
		if(kvmTable != null) {	
			TableParser mTableParser = null;
			for(int i=0;i<kvmTable.size();i++){
				mTableParser = new TableParser(this.trgDb,kvmTable.get(i));
				importMD(this.trgDb,mTableParser.getCreate(),mJda,ignoreSqlError);
				importMD(this.trgDb,mTableParser.getCreatePK(),mJda,ignoreSqlError);
				importMD(this.trgDb,mTableParser.getCreateIndex(),mJda,ignoreSqlError);
			}
		}
	}

	/**
	 * 执行DDL语句
	 * @throws ErrorMessage
	 */
	private void fkExecute(boolean ignoreSqlError,Jda mJda) throws ErrorMessage{
		if(kvmTable != null) {	
			TableParser mTableParser = null;
			for(int i=0;i<kvmTable.size();i++){
				mTableParser = new TableParser(this.trgDb,kvmTable.get(i));
				importMD(this.trgDb,mTableParser.getCreateFK(),mJda,ignoreSqlError);
			}
		}
	}
	/**
	 * 功能  导入执行
	 * @param mdDbResource  元数据库数据源信息
	 * @param mSql          Sql对象
	 * @throws ErrorMessage
	 */
	private void importMD(DbResource mdDbResource,Sql mSql,Jda mJda,
			boolean ignoreSqlError) throws ErrorMessage{
		if(mSql==null || mSql.toString()==null) return ;
		String sql = mSql.toString();
		if(sql.lastIndexOf(";")!=-1){
			sql = sql.substring(0,sql.lastIndexOf(";"));
		}
		String[] sqls = sql.split(";");
		for(int i=0;i<sqls.length;i++){
			if(sqls[i]!=null && !sqls[i].trim().equals("")){
				try {
					mJda.executeDDL(new Sql(sqls[i]));
				} catch (ErrorMessage e) {
					if(ignoreSqlError){
						DEBUG.println("【Warnning】\t"+e.getMessage());
					}else
						throw e;
				} catch (Exception e){
					throw new ErrorMessage(e,sql);
				}
			}
		}	
	}

}
